package com.gzc.just.play.last.war.common.connection;

import com.gzc.just.play.last.war.common.distributed.ServiceInstance;
import com.gzc.just.play.last.war.common.registry.ServiceDiscovery;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

/**
 * Nacos感知的连接器基类
 * 订阅Nacos服务发现，等待依赖服务TCP就绪后再建立连接
 */
public abstract class NacosAwareConnector {
    
    protected static final Logger logger = LoggerFactory.getLogger(NacosAwareConnector.class);
    
    @Autowired(required = false)
    protected ServiceDiscovery serviceDiscovery;
    
    @Autowired
    protected ServerConnectionManager connectionManager;
    
    @Value("${spring.cloud.nacos.discovery.enabled:true}")
    protected boolean nacosEnabled;
    
    // 已连接的服务实例缓存
    protected final Map<String, ServiceInstance> connectedInstances = new ConcurrentHashMap<>();
    
    /**
     * 初始化连接
     * 根据Nacos开关，选择使用Nacos模式或静态配置模式
     */
    protected void initializeConnections() {
        logger.info("Initializing connections, nacosEnabled={}", nacosEnabled);
        
        if (nacosEnabled && serviceDiscovery != null) {
            // 使用Nacos模式
            initializeWithNacos();
        } else {
            // 使用静态配置模式（兼容旧逻辑）
            initializeWithStaticConfig();
        }
    }
    
    /**
     * 使用Nacos初始化连接
     */
    protected void initializeWithNacos() {
        logger.info("Initializing connections with Nacos service discovery");
        
        // 获取需要连接的服务列表
        Map<String, ServerConnectionManager.ServerType> dependencies = getDependencies();
        
        for (Map.Entry<String, ServerConnectionManager.ServerType> entry : dependencies.entrySet()) {
            String serviceName = entry.getKey();
            ServerConnectionManager.ServerType serverType = entry.getValue();
            
            try {
                // 订阅服务变更
                serviceDiscovery.subscribe(serviceName, instances -> {
                    handleServiceInstancesChange(serviceName, serverType, instances);
                });
                
                logger.info("Subscribed to service: {}", serviceName);
            } catch (Exception e) {
                logger.error("Failed to subscribe to service: {}", serviceName, e);
            }
        }
        
        // 启动心跳检测
        connectionManager.startHeartbeat();
    }
    
    /**
     * 使用静态配置初始化连接（兼容模式）
     */
    protected abstract void initializeWithStaticConfig();
    
    /**
     * 获取依赖的服务映射
     * key: 服务名称（Nacos中的服务名）
     * value: ServerType（连接管理器中的服务类型）
     */
    protected abstract Map<String, ServerConnectionManager.ServerType> getDependencies();
    
    /**
     * 处理服务实例变更
     */
    protected void handleServiceInstancesChange(String serviceName, 
                                               ServerConnectionManager.ServerType serverType,
                                               List<ServiceInstance> instances) {
        logger.debug("Service {} instances changed, count={}", serviceName, instances.size());
        
        // 过滤TCP就绪的实例
        List<ServiceInstance> readyInstances = instances.stream()
                .filter(this::isTcpReady)
                .toList();
        
        if (readyInstances.isEmpty()) {
            logger.info("No TCP-ready instances found for service: {}", serviceName);
            return;
        }
        
        // 选择第一个就绪实例（可以扩展为负载均衡策略）
        ServiceInstance instance = readyInstances.get(0);
        
        // 检查是否已经连接到该实例
        ServiceInstance connected = connectedInstances.get(serviceName);
        if (connected != null && connected.equals(instance)) {
            logger.debug("Already connected to service instance: {}", instance);
            return;
        }
        
        // 建立新连接
        connectToInstance(serviceName, serverType, instance);
    }
    
    /**
     * 检查服务实例是否TCP就绪
     */
    protected boolean isTcpReady(ServiceInstance instance) {
        String tcpReady = instance.getMetadata("tcpReady");
        return "true".equalsIgnoreCase(tcpReady);
    }
    
    /**
     * 连接到服务实例
     */
    protected void connectToInstance(String serviceName, 
                                    ServerConnectionManager.ServerType serverType,
                                    ServiceInstance instance) {
        logger.info("Connecting to service instance: serviceName={}, host={}, port={}", 
                   serviceName, instance.getHost(), instance.getPort());
        
        // 注册服务器配置
        connectionManager.registerServerConfig(
                serverType,
                new ServerConnectionManager.ServerConfig(instance.getHost(), instance.getPort())
        );
        
        // 建立连接（带重试）
        connectWithRetry(serviceName, serverType, instance, 0);
    }
    
    /**
     * 带重试的连接建立
     */
    protected void connectWithRetry(String serviceName,
                                   ServerConnectionManager.ServerType serverType,
                                   ServiceInstance instance,
                                   int retryCount) {
        final int maxRetries = 3;
        final long retryDelay = 5;
        
        connectionManager.connectToServer(serverType)
                .thenAccept(channel -> {
                    connectedInstances.put(serviceName, instance);
                    logger.info("Successfully connected to service: {}", serviceName);
                })
                .exceptionally(throwable -> {
                    logger.error("Failed to connect to service: {}, retry count: {}", 
                               serviceName, retryCount, throwable);
                    
                    if (retryCount < maxRetries) {
                        // 延迟重试
                        try {
                            TimeUnit.SECONDS.sleep(retryDelay);
                            connectWithRetry(serviceName, serverType, instance, retryCount + 1);
                        } catch (InterruptedException e) {
                            Thread.currentThread().interrupt();
                            logger.error("Retry interrupted", e);
                        }
                    } else {
                        logger.error("Max retries reached for service: {}", serviceName);
                    }
                    
                    return null;
                });
    }
    
    /**
     * 关闭连接
     */
    protected void shutdownConnections() {
        logger.info("Shutting down connections...");
        
        if (nacosEnabled && serviceDiscovery != null) {
            // 取消订阅所有服务
            Map<String, ServerConnectionManager.ServerType> dependencies = getDependencies();
            for (String serviceName : dependencies.keySet()) {
                try {
                    serviceDiscovery.unsubscribe(serviceName);
                    logger.info("Unsubscribed from service: {}", serviceName);
                } catch (Exception e) {
                    logger.error("Failed to unsubscribe from service: {}", serviceName, e);
                }
            }
        }
        
        // 停止心跳
        connectionManager.stopHeartbeat();
        
        // 关闭所有连接
        connectionManager.shutdownAll();
        
        connectedInstances.clear();
        
        logger.info("Connections shutdown completed");
    }
}
